# coding=utf8

import json
import sys
import os

__author__ = "zouxiaoliang"


CONFIG_PATH = 'config.json'

PROJECT_NAME = "project(%s)"
CMAKE_MINIMUM_REQUIRED = "cmake_minimum_required(VERSION %s)"
INPUT_CHARSET = "GBK"
OUTPUT_CHARSET = "UTF8"
CMAKE_CXX_FLAGS = "set(CMAKE_CXX_FLAGS \"%s\")"
CMAKE_CXX_FLAGS_DEBUG = "set(CMAKE_CXX_FLAGS_DEBUG \"%s\")"
CMAKE_CXX_FLAGS_RELEASE = "set(CMAKE_CXX_FLAGS_RELEASE \"%s\")"
LIB_VERSION = "set(LIB_VERSION %s)"
INCLUDE_PATH = "include_directories(%s)"
SOURCE_DIRECTORY = "aux_source_directory(%s SRC)"
LINK_DIRECTORIES = "link_directories(%s)"
ADD_DEFINITIONS = "add_definitions(%s)"
ADD_LIBRARY = "add_library(${PROJECT_NAME} %s ${SRC})"
ADD_EXECUTABLE = "add_executable(${PROJECT_NAME} ${SRC})"
EXECUTABLE_OUTPUT_PATH = "set(EXECUTABLE_OUTPUT_PATH %s)"
TARGET_LINK_LIBRARIES = "target_link_libraries(${PROJECT_NAME} %s)"


def dir_check(path):
    if not os.path.isdir(path):
        return False

    dir_name = os.path.basename(path)
    if '.' == dir_name[0]:
        return False

    return True


def lsdir(path, condition):
    """
    获取当前指定目录下的指定规则的路径
    :param path:
    :param condition:
    :return:
    """
    # print(path)
    dir_list = []
    file_list = os.listdir(path)
    for file_name in file_list:
        if condition is not None and condition(path + os.path.sep + file_name):
            # print(path + os.path.sep + file_name)
            dir_list.append(path + os.path.sep + file_name)
            sub_list = lsdir(path + os.path.sep + file_name, condition)
            for sub in sub_list:
                dir_list.append(sub)
    return dir_list


def _build_cmake_list(cmds):
    """

    :param cmds:
    :return:
    """
    cmake_file = open("CMakeLists.txt", mode="w")
    for cmd, params in cmds:
        # print(cmd, params)
        if params is None:
            cmake_file.write(cmd)
        else:
            cmake_file.write(cmd % params)
        cmake_file.write("\n")
    cmake_file.close()


def main():
    if not os.path.exists(CONFIG_PATH):
        sys.exit(1)

    json_handle = open(CONFIG_PATH, mode='r')
    project_config = json.load(json_handle)
    if None is project_config:
        sys.exit(1)

    lines = []

    if str(project_config["project_type"]).lower() not in ["app", "shared", "static"]:
        sys.exit(1)

    lines.append((CMAKE_MINIMUM_REQUIRED, "2.8"))

    # 设置项目名称
    if "project_name" not in project_config.keys():
        app_name = "app"
    else:
        app_name = project_config["project_name"]

    lines.append((PROJECT_NAME, app_name))

    # 设置版本信息
    if str(project_config["project_type"]).lower() in ["shared", "static"]:
        if "project_version" not in project_config.keys():
            lines.append((LIB_VERSION, "1.0.1"))
        else:
            lines.append((LIB_VERSION, project_config["project_version"]))

    # 包含头文件
    lines.append((INCLUDE_PATH, "."))
    lines.append((SOURCE_DIRECTORY, "."))
    if "include" in project_config.keys():
        for include in project_config["include"]:
            lines.append((INCLUDE_PATH, include))

    # 包含源代码及头文件
    if "src" in project_config.keys():
        for src in project_config["src"]:
            sub_src = lsdir(src, dir_check)
            for sub in sub_src:
                lines.append((INCLUDE_PATH, sub))
            lines.append((INCLUDE_PATH, src))

        for src in project_config["src"]:
            sub_src = lsdir(src, dir_check)
            for sub in sub_src:
                lines.append((SOURCE_DIRECTORY, sub))
            lines.append((SOURCE_DIRECTORY, src))

    # 添加依赖库路径
    if "lib_path" in project_config.keys():
        for lib_path in project_config["lib_path"]:
            lines.append((LINK_DIRECTORIES, lib_path))

    # 设置生成目标
    if project_config["project_type"].lower() in ["shared", "static"]:
        lines.append((ADD_LIBRARY, project_config["project_type"].upper()))
    else:
        lines.append((ADD_EXECUTABLE, None))

    # 添加依赖库
    if "lib_name" in project_config.keys():
        for lib_name in project_config["lib_name"]:
            lines.append((TARGET_LINK_LIBRARIES, lib_name))

    # 添加cxx标记
    if "cxx_flag" in project_config.keys():
        cxx_flag = project_config["cxx_flag"]
        if "debug" in cxx_flag.keys():
            if len(cxx_flag["debug"]) != 0:
                debug_flag = " ".join(debug for debug in cxx_flag["debug"])
                lines.append((CMAKE_CXX_FLAGS_DEBUG, debug_flag))
        if "release" in cxx_flag.keys():
            if len(cxx_flag["debug"]) != 0:
                release_flag = " ".join(release for release in cxx_flag["release"])
                lines.append((CMAKE_CXX_FLAGS_RELEASE, release_flag))
        if "flag" in cxx_flag.keys():
            if len(cxx_flag["flag"]) != 0:
                flag_flag = " ".join(one_flag for one_flag in cxx_flag["flag"])
                lines.append((CMAKE_CXX_FLAGS, flag_flag))

    # 添加宏标记
    if "defines" in project_config.keys():
        for define in project_config["defines"]:
            lines.append((ADD_DEFINITIONS, "-D"+define))

    # 输出路径
    if "out" in project_config.keys():
        lines.append((EXECUTABLE_OUTPUT_PATH, project_config["out"]))

    _build_cmake_list(lines)
    pass


def test():
    lsdir("/Users/zouxiaoliang/workspace/QtProjects/msgplus/subscribe-demo", dir_check)

if __name__ == '__main__':
    main()
